//
//  WaterFallScrollView.m
//  瀑布流1
//
//  Created by yuanyuan on 15-3-9.
//  Copyright (c) 2015年 hanjiaxue. All rights reserved.
//

#import "WaterFallScrollView.h"
#import "WaterFallViewCell.h"

#define YYWaterflowViewDefaultNumberOfClunms  3
#define YYWaterflowViewDefaultCellH  100
#define YYWaterflowViewDefaultMargin 10

@implementation WaterFallScrollView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

#pragma mark-懒加载
-(NSMutableArray *)cellFrames
{
    if (_cellFrames==nil) {
        _cellFrames=[NSMutableArray array];
    }
    return _cellFrames;
}

-(NSMutableDictionary *)displayingCells
{
    if (_displayingCells==nil) {
        _displayingCells=[NSMutableDictionary dictionary];
    }
    return _displayingCells;
}

-(NSMutableSet *)reusableCells
{
    if (_reusableCells==nil) {
        _reusableCells=[NSMutableSet set];
    }
    return _reusableCells;
}


-(void)willMoveToSuperview:(UIView *)newSuperview
{
    [self reloadData];
}

#pragma mark-公共方法
/**
 *  cell的宽度
 */
-(CGFloat)cellWidth
{
    //cell的列数
    int numberOfColumns=[self numberOfColumns];
    CGFloat leftM=[self marginForType:YYWaterflowViewMarginTypeLeft];
    CGFloat rightM=[self marginForType:YYWaterflowViewMarginTypeRight];
    CGFloat columnM=[self marginForType:YYWaterflowViewMarginTypeColumn];
    return (self.frame.size.width-leftM-rightM-(numberOfColumns-1)*columnM)/numberOfColumns;
}

/**
 *  刷新数据
 *  1.计算每个cell的frame
 */
-(void)reloadData
{
    
    [self.displayingCells.allValues makeObjectsPerformSelector:@selector(removeFromSuperview)];//把字典中所有的值都从屏幕上移除
    [self.displayingCells removeAllObjects];//清除字典中得所有元素
    [self.cellFrames removeAllObjects];//清除cell的frame，每个位置的cell的frame都要重新计算
    [self.reusableCells removeAllObjects];//清除可复用的缓存池
    
    
    
    //cell的总数是多少
    int numberOfCells=[self.dadaSource numberOfCellsInWaterflowView:self];
    
    //cell的列数
    int numberOfColumns=[self numberOfColumns];
    
    //间距
    CGFloat leftM=[self marginForType:YYWaterflowViewMarginTypeLeft];
    
    CGFloat columnM=[self marginForType:YYWaterflowViewMarginTypeColumn];
    CGFloat topM=[self marginForType:YYWaterflowViewMarginTypeTop];
    CGFloat rowM=[self marginForType:YYWaterflowViewMarginTypeRow];
    CGFloat bottomM=[self marginForType:YYWaterflowViewMarginTypeBottom];
    
    //（1）cell的宽度
    //cell的宽度=（整个view的宽度-左边的间距-右边的间距-（列数-1）X每列之间的间距）/总列数
    //    CGFloat cellW=(self.frame.size.width-leftM-rightM-(numberOfColumns-1)*columnM)/numberOfColumns;
    CGFloat cellW=[self cellWidth];
    
    //用一个C语言的数组来存放所有列的最大的Y值
    CGFloat maxYOfColumns[numberOfColumns];
    for (int i=0; i<numberOfColumns; i++) {
        //初始化数组的数值全部为0
        maxYOfColumns[i]=0.0;
    }
    
    
    //计算每个cell的fram
    for (int i=0; i<numberOfCells; i++) {
        
        //(2)cell的高度
        //询问代理i位置的高度
        CGFloat cellH=[self heightAtIndex:i];
        
        //cell处在第几列（最短的一列）
        NSUInteger cellAtColumn=0;
        
        //cell所处那列的最大的Y值（当前最短的那一列的最大的Y值）
        //默认设置最短的一列为第一列（优化性能）
        CGFloat maxYOfCellAtColumn=maxYOfColumns[cellAtColumn];
        
        //求出最短的那一列
        for (int j=0; j<numberOfColumns; j++) {
            if (maxYOfColumns[j]<maxYOfCellAtColumn) {
                cellAtColumn=j;
                maxYOfCellAtColumn=maxYOfColumns[j];
            }
        }
        
        //（3）cell的位置（X,Y）
        //cell的X=左边的间距+列号*（cell的宽度+每列之间的间距）
        CGFloat cellX=leftM+cellAtColumn*(cellW +columnM);
        //cell的Y，先设定为0
        CGFloat cellY=0;
        if (maxYOfCellAtColumn==0.0) {//首行
            cellY=topM;
        }else
        {
            cellY=maxYOfCellAtColumn+rowM;
        }
        
        //设置cell的frame并添加到数组中
        CGRect cellFrame=CGRectMake(cellX, cellY, cellW, cellH);
        [self.cellFrames addObject:[NSValue valueWithCGRect:cellFrame]];
        
        //更新最短那一列的最大的Y值
        maxYOfColumns[cellAtColumn]=CGRectGetMaxY(cellFrame);
        
        //显示cell
        //        YYWaterflowViewCell *cell=[self.dadaSource waterflowView:self cellAtIndex:i];
        //        cell.frame=cellFrame;
        //        [self addSubview:cell];
    }
    
    //设置contentSize
    CGFloat contentH=maxYOfColumns[0];
    
    for (int i=1; i<numberOfColumns; i++) {
        if (maxYOfColumns[i]>contentH) {
            contentH=maxYOfColumns[i];
        }
    }
    contentH += bottomM;
    self.contentSize=CGSizeMake(0, contentH);
}

/**
 *  当UIScrollView滚动的时候也会调用这个方法
 */
-(void)layoutSubviews
{
    [super layoutSubviews];
    
    [self reloadData];
    
//    NSLog(@"%d dfdfdfd",self.cellFrames.count);
    
    //向数据源索要对应位置的cell
    NSUInteger numberOfCells=self.cellFrames.count;
 
    for (int i=0; i<numberOfCells; i++) {
        //取出i位置的frame,注意转换
        CGRect cellFrame=[self.cellFrames[i] CGRectValue];
        
        //优先从字典中取出i位置的cell
        WaterFallViewCell *cell=self.displayingCells[@(i)];
        
        //判断i位置对应的frame在不在屏幕上（能否看见）
        if ([self isInScreen:cellFrame]) {//在屏幕上
            if (cell==nil) {
                cell= [self.dadaSource waterflowView:self cellAtIndex:i];
                cell.frame=cellFrame;
                [self addSubview:cell];
                
                //存放在字典中
                self.displayingCells[@(i)]=cell;
            }
            
        }else //不在屏幕上
        {
            if (cell) {
                //从scrollView和字典中删除
                [cell removeFromSuperview];
                [self.displayingCells removeObjectForKey:@(i)];
                
                //存放进缓存池
                [self.reusableCells addObject:cell];
            }
        }
    }
    //       NSLog(@"%d",self.subviews.count);
}

-(id)dequeueReusableCellWithIdentifier:(NSString *)identifier
{
    __block WaterFallViewCell *reusableCell=nil;
    [self.reusableCells enumerateObjectsUsingBlock:^(WaterFallViewCell *cell, BOOL *stop) {
        if ([cell.identifier isEqualToString:identifier]) {
            reusableCell=cell;
            *stop=YES;
        }
    }];
    
    if (reusableCell) {//从缓存池中移除（已经用掉了）
        [self.reusableCells removeObject:reusableCell];
    }
    return reusableCell;
}

#pragma mark cell的事件处理
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    //如果没有点击事件的代理方法，那么就直接返回
    if (![self.delegate respondsToSelector:@selector(waterflowView:didSelectAtIndex:)])
        return;
    
    //获得手指在屏幕上点击的触摸点
    UITouch *touch=[touches anyObject];
    CGPoint point1=[touch locationInView:touch.view];
    CGPoint point=[touch locationInView:self];
    NSLog(@"%@--%@",NSStringFromCGPoint(point),NSStringFromCGPoint(point1));
    
    __block NSNumber *selectIndex=nil;
    [self.displayingCells enumerateKeysAndObjectsUsingBlock:^(id key, WaterFallViewCell *cell, BOOL *stop) {
        if (CGRectContainsPoint(cell.frame, point)) {
            selectIndex=key;
            *stop=YES;
        }
    }];
    if (selectIndex) {
        //需要转换
        [self.delegate waterflowView:self didSelectAtIndex:selectIndex.unsignedIntegerValue];
    }
    
}
#pragma mark-私有方法
/**
 *  判断一个人cell的frame有没有显示在屏幕上
 */
-(BOOL)isInScreen:(CGRect)frame
{
    //    return (CGRectGetMaxY(frame)>self.contentOffset.y)&&(CGRectGetMaxY(frame)<self.contentOffset.y+self.frame.size.height);
    return (CGRectGetMaxY(frame) > self.contentOffset.y) &&
    (CGRectGetMinY(frame) < self.contentOffset.y + self.frame.size.height);
    
}
-(CGFloat)marginForType:(YYWaterflowViewMarginType)type
{
    if ([self.delegate respondsToSelector:@selector(waterflowView:marginForType:)]) {
        return  [self.delegate waterflowView:self marginForType:type];
    }else
    {
        return YYWaterflowViewDefaultMargin;
    }
}

-(NSUInteger)numberOfColumns
{
    if ([self.dadaSource respondsToSelector:@selector(numberOfColumnsInWaterflowView:)]) {
        return [self.dadaSource numberOfColumnsInWaterflowView:self];
    }else
    {
        return  YYWaterflowViewDefaultNumberOfClunms;
    }
}

-(CGFloat)heightAtIndex:(NSUInteger)index
{
    if ([self.delegate respondsToSelector:@selector(waterflowView:heightAtIndex:)]) {
        return [self.delegate waterflowView:self heightAtIndex:index];
    }else
    {
        return YYWaterflowViewDefaultCellH;
    }
}












@end
